<?php

namespace App\Services;

use App\ModelCategory;
use App\ModelClass;
use App\ModelClassProperty;
use App\Model;
use App\Lib\Util\QueryPager;
use DB;

class ModelClassService
{
    private function baseQuery()
    {
        return ModelClass::select('id', 'code', 'name', 'sort_order', 'category_id');
    }

    public function getClasses(Array $input, $paging = true)
    {
        $query = $this->baseQuery();

        if (!empty($input['categoryId'])) {
            $modelCategoryService = new ModelCategoryService();
            $allChildrenCategories = $modelCategoryService->getCascadeCategories(
                ModelCategory::select('id', 'name', 'parent_id')->where('id', $input['categoryId'])->first()->toArray()
            );
            $query = $query->whereIn('category_id', collect($allChildrenCategories)->pluck('id')->toArray());
        }

        if (!empty($input['name'])) {
            $query->where('name', 'like', '%'.$input['name'].'%');
        }

        if (!empty($input['code'])) {
            $query->where('code', 'like', '%'.$input['code'].'%');
        }

        $pager = new QueryPager($query);

        $pager->setRefectionMethodField('getFullPath');

        return $paging ? $pager->doPaginate($input, 'sort_order') :
            $pager->queryWithoutPaginate($input, 'sort_order');
    }

    public function getCategoryClass($categoryId)
    {
        return ModelClass::where('category_id', $categoryId)->orderBy('sort_order')->get();
    }

    public function getClassDetails($classId)
    {
        return ModelClassProperty::where('class_id', $classId)->orderBy('sort_order')->get();
    }

    public function saveNewClass(Array $class, Array $items)
    {
        DB::transaction(function () use ($class, $items) {
            $modelClass = ModelClass::create([
                'code' => $class['code'],
                'name' => $class['name'],
                'sort_order' => $class['sort_order'],
                'category_id' => $class['category_id']
            ]);

            $order = 0;
            foreach ($items as $item) {
                $order++;
                ModelClassProperty::create([
                    'name' => $item['name'],
                    'value' => $item['value'],
                    'sort_order' => $order,
                    'class_id' => $modelClass->id
                ]);
            }
        });
    }

    public function saveUpdateClass(Array $class, Array $items)
    {
        DB::transaction(function () use ($class, $items) {
            $modelClass = ModelClass::findOrFail($class['id']);

            $modelClass->update([
                'id' => $class['id'],
                'code' => $class['code'],
                'name' => $class['name'],
                'sort_order' => $class['sort_order'],
                'category_id' => $class['category_id']
            ]);

            $order = 0;
            $releaseProps = [];
            foreach ($items as $item) {
                $order++;
                if (!empty($item['id'])) {
                    $modelClassProperty = ModelClassProperty::findOrFail($item['id']);

                    $modelClassProperty->update([
                        'id' => $item['id'],
                        'name' => $item['name'],
                        'value' => $item['value'],
                        'sort_order' => $order,
                    ]);

                    array_push($releaseProps, $modelClassProperty->id);
                } else {
                    $modelClassProperty = ModelClassProperty::create([
                        'name' => $item['name'],
                        'value' => $item['value'],
                        'sort_order' => $order,
                        'class_id' => $modelClass->id
                    ]);

                    array_push($releaseProps, $modelClassProperty->id);
                }
            }

            ModelClassProperty::where('class_id', $modelClass->id)->whereNotIn('id', $releaseProps)->delete();
        });
    }

    public function deleteClass($classId)
    {
        DB::transaction(function () use ($classId) {

            ModelClassProperty::where('class_id', $classId)->delete();

            $class = ModelClass::findOrFail($classId);
            $class->delete();
        });
    }

    public function hasConstrait($classId)
    {
        return ModelClassProperty::where('class_id', $classId)->count() > 0 && Model::where('class_id', $classId)->count() > 0;
    }
}
